# coding: utf-8

import base64
import os
from cStringIO import StringIO

import pytesseract
from PIL import Image, ImageDraw

import handler.http as httpHandler


def image_to_string(image, lang=None):
    code = pytesseract.image_to_string(image, lang=lang)
    if code:
        code = code.strip()
        code = code.replace(' ', '')
        code = code.replace('|', 'l')
        code = code.replace(os.linesep, '')
    return code


def download_to_image(image_url, headers=None, cookies=None):
    response = httpHandler.get(image_url, headers=headers, cookies=cookies, stream=True)
    byte_data_list = ''
    for byte in response:
        byte_data_list += byte
    binary_data = StringIO(byte_data_list)
    return Image.open(binary_data)


def image_to_base64(image, format='JPEG'):
    data_buffer = StringIO()
    image.save(data_buffer, format=format)
    return base64.b64encode(data_buffer.getvalue())


''' 获取灰度转二值的映射table '''
def get_bin_table(threshold=140):
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    return table

def binarizing(image, threshold):
    image = image.convert('L')
    pixdata = image.load()
    w, h = image.size
    # 遍历所有像素，大于阈值的为黑色
    for y in range(h):
        for x in range(w):
            if pixdata[x, y] < threshold:
                pixdata[x, y] = 0
            else:
                pixdata[x, y] = 255
    return image


def binaryzation(img, threshold=30):
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    width, height = img.size
    pixdata = img.load()
    for x in xrange(width):
        for y in xrange(height):
            r, g, b, _ = pixdata[x, y]
            if r > threshold or g > threshold or b > threshold:
                pixdata[x, y] = WHITE
            else:
                pixdata[x, y] = BLACK


def remove_line(image):
    # import random
    width, height = image.size
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    pixdata = image.load()
    for x in xrange(width):
        count = 0
        c_count = 0
        s_count = 0
        flag = False
        for y in xrange(height):
            if x == 0 and pixdata[x + 1, y] == WHITE:
                pixdata[x, y] = WHITE
            elif x > 0 and x < width - 1 and pixdata[x - 1, y] == WHITE and pixdata[x + 1, y] == WHITE:
                pixdata[x, y] = WHITE
            elif x == width - 1 and pixdata[x - 1, y] == WHITE:
                pixdata[x, y] = WHITE
            if pixdata[x, y] == BLACK:
                count += 1
                flag = True
            elif count != 0:
                if flag == True:
                    c_count += 1
                    s_count = count
                    flag = False
                if count == 1:
                    pixdata[x, y - 1] = WHITE
                # if count <= 5:
                #     print(count)
                #     for k in range(count):
                #         pixdata[x, y-k-1] = WHITE
                count = 0
        if c_count == 1 and s_count < 10:
            for y in xrange(height):
                # if random.randint(0, 10) % 2 == 0:
                pixdata[x, y] = WHITE


def image_rmeove_interfere(image, px=2):
    width, height = image.size
    pixdata = image.load()
    for x in xrange(1, width):
        list_y = []
        for y in xrange(1, height):
            count = 0
            r, g, b = image.getpixel((x, y))
            while y < (height - 1) and (r + g + b) < 10:
                y += 1
                count += 1
            if count <= px and count > 0:
                for i in xrange(count):
                    list_y.append(y - i)
        if len(list_y):
            for temp_y in list_y:
                # image.putpixel((x, temp_y), 0)
                pixdata[x, temp_y] = (255,255,255)
    return image


''' 裁剪图片
location：left, top, right, bottom 
'''
def cut_verify_code_image(image, location):
    verify_code_image = image.crop(location)
    return verify_code_image


def data_to_image(image_data):
    binary_data = StringIO(image_data)
    image = Image.open(binary_data)
    return image


def is_similar(image, image_new, x, y):
    pixel = image.getpixel((x, y))
    pixel_new = image_new.getpixel((x, y))
    for i in range(0, 3):
        if abs(pixel[i] - pixel_new[i]) >= 50:
            return False
    return True


def get_diff_location(image, image_new):
    w, h = image.size
    for i in range(0, w):
        for j in range(0, h):
            if is_similar(image, image_new, i, j) is False:
                return i
    return 0


''' 二值判断,如果确认是噪声,用改点的上面一个点的灰度进行替换
    该函数也可以改成RGB判断的,具体看需求如何
'''
def get_pixel(image, x, y, G, N):
    L = image.getpixel((x, y))
    L = L > G
    nearDots = 0
    if L == (image.getpixel((x - 1, y - 1)) > G):
        nearDots += 1
    if L == (image.getpixel((x - 1, y)) > G):
        nearDots += 1
    if L == (image.getpixel((x - 1, y + 1)) > G):
        nearDots += 1
    if L == (image.getpixel((x, y - 1)) > G):
        nearDots += 1
    if L == (image.getpixel((x, y + 1)) > G):
        nearDots += 1
    if L == (image.getpixel((x + 1, y - 1)) > G):
        nearDots += 1
    if L == (image.getpixel((x + 1, y)) > G):
        nearDots += 1
    if L == (image.getpixel((x + 1, y + 1)) > G):
        nearDots += 1
    if nearDots < N:
        return image.getpixel((x, y - 1))
    else:
        return None


# 根据一个点A的RGB值，与周围的8个点的RBG值比较，设定一个值N（0 <N <8），当A的RGB值与周围8个点的RGB相等数小于N时，此点为噪点
# G: Integer 图像二值化阀值
# N: Integer 降噪率 0 <N <8
# Z: Integer 降噪次数
# 输出
#  0：降噪成功
#  1：降噪失败
def clear_noise(image, G=50, N=4, Z=4):
    draw = ImageDraw.Draw(image)
    for i in range(0, Z):
        for x in range(1, image.size[0] - 1):
            for y in range(1, image.size[1] - 1):
                color = get_pixel(image, x, y, G, N)
                if color != None:
                    draw.point((x, y), color)


def image_to_ascii(image):
    width, height = image.size
    image = image.convert('L')
    image = image.convert('1')
    string = str()
    for y in range(height):
        for x in range(width):
            string += '%d ' % (1 if image.getpixel((x, y)) == 0 else 0)
        string += os.linesep
    return string
